//this class use qt library timer to implement timerimpl interface
//andycai_sc 2011-05-29

#ifndef QTTIMERIMPL_H
#define QTTIMERIMPL_H

#include "GParallel/GTimerImpl.h"
#include <QTimer>

//--------------------------this timer slot function run in main thread--------------------

class QtCommonTimerImpl : public QObject, public GTimerImpl
{
    Q_OBJECT
public:
    QtCommonTimerImpl(GTimer* timer, QObject* parent = 0);
    virtual ~QtCommonTimerImpl();

    void beginImpl(long millisc);

    void cancelImpl();

private slots:
    void runTask();

private:
    QTimer m_qTimer;
};

//----------------QThreadTimerImpl create timer in another thread---------------
//----------------for not blocked by the main thread slot function--------------

#include <QThread>
#include <QMutex>
#include <QHash>

class TimerThread;
class TimerTask;
class QtThreadTimerImpl : public QObject, public GTimerImpl
{
    friend class TimerTask;
    Q_OBJECT
public:
    QtThreadTimerImpl(GTimer* gtimer, QObject* parent = 0);
    virtual ~QtThreadTimerImpl();

    void beginImpl(long millisc);

    void cancelImpl();

private:
    TimerThread& m_timerThrRef;
    TimerTask* m_timerTask;
};

//------------------------TimerTask use to execute timer schedule----------------------

class TimerTask : public QObject
{
    Q_OBJECT
public:
    TimerTask(GTimerImpl* timerImpl, QObject* parent = 0);

    void start(long mseconds);

    void stop();

public slots:
    void task();

signals:
    void begin(int msecs);
    void end();

private:
    QTimer m_timer;
    GTimerImpl* m_timerImpl;
};

class TaskContainer : public QObject
{
    Q_OBJECT
public:
    TaskContainer(QObject* parent = 0);

    TimerTask* getTimerTask(GTimerImpl* timerImpl);

    void removeTimer(GTimerImpl* timerImpl);

    bool isEmpty() const;

public slots:
    void addTimer(GTimerImpl* timerImpl);

private:
    QHash<GTimerImpl*, TimerTask*> m_timerTasks;
    QMutex m_taskMutex;
};

class TimerThread : public QThread
{
    Q_OBJECT
public:
    static TimerThread& instance();

    TimerTask* getTimerTask(GTimerImpl* timerImpl);
    TaskContainer* getTaskContainer();

    void appendTimer(GTimerImpl* timerImpl);
    void deleteTimer(GTimerImpl* timerImpl);

    void mSleep(unsigned long msec);

signals:
    void newTimer(GTimerImpl* timerImpl);
    void timerRemove(GTimerImpl* timerImpl);

private:
    void run();

private:
    TimerThread(QObject *parent = 0);
    static TimerThread _timerThread;
    TaskContainer* m_taskContainer;
};

#endif
